#ifndef __VARIABLE_HEAD
#define __VARIABLE_HEAD

struct Table ; 
/* values */

typedef unsigned long ITEM;

enum BaseType
{
    TypeVoid,                   /* no type */
    TypeInt,                    /* integer */
    TypeShort,                  /* short integer */
    TypeChar,                   /* a single character (unsigned) */
    TypeLong,                   /* long integer */
    TypeUnsignedInt,            /* unsigned integer */
    TypeUnsignedShort,          /* unsigned short integer */
    TypeUnsignedLong,           /* unsigned long integer */
    TypeFP,                     /* floating point */
    TypeFunction,               /* a function */
    TypeMacro,                  /* a macro */
    TypePointer,                /* a pointer */
    TypeArray,                  /* an array of a sub-type */
    TypeStruct,                 /* aggregate type */
    TypeUnion,                  /* merged type */
    TypeEnum,                   /* enumerated integer type */
    TypeGotoLabel,              /* a label we can "goto" */
    TypeString,     
    TypeMatrix,
    TypeList,
    TypeDLList,
    TypeSortedList,
    TypeArrayList,
    TypeHashMap,
    TypeRelationGraph,
    TypeDirectGraph,
    TypeUnDirectGraph,
    TypeItem,
    TypeItemList,
    Type_Type                   /* a type for storing types */
};

/* data type */
struct ValueType
{
    enum BaseType Base;             /* what kind of type this is */
    int ArraySize;                  /* the size of an array type */
    int Sizeof;                     /* the storage required */
    int AlignBytes;                 /* the alignment boundary of this type */
    const char *Identifier;         /* the name of a struct or union */
    struct ValueType *Dims;	    /* the dimentions parameters for matrix */
    struct ValueType *FromType;     /* the type we're derived from (or NULL) */
    struct ValueType *DerivedTypeList;  /* first in a list of types derived from this one */
    struct ValueType *Next;         /* next item in the derived type list */

};

/* function definition */
struct FuncDef
{
    struct ValueType *ReturnType;   /* the return value type */
    int NumParams;                  /* the number of parameters */
    int VarArgs;                    /* has a variable number of arguments after the explicitly specified ones */
    struct ValueType **ParamType;   /* array of parameter types */
    char **ParamName;               /* array of parameter names */
    void (*Intrinsic)(int,...);     /* intrinsic call address or NULL */
 
};

/* values */
union AnyValue
{
    char *Identifier;
    unsigned char Character;
    short ShortInteger;
    int Integer;
    long LongInteger;
    unsigned short UnsignedShortInteger;
    unsigned int UnsignedInteger;
    unsigned long UnsignedLongInteger;
    char ArrayMem[2];               /* placeholder for where the data starts, doesn't point to it */

    ITEM_LIST *items;

    struct ValueType *Typ;
    struct FuncDef FuncDef;

    double FP;

    void *Pointer;                  /* unsafe native pointers */
};

struct Value
{
    struct ValueType *Typ;       /* the type of this value */
    union AnyValue *Val;         /* pointer to the AnyValue which holds the actual content */
    struct Value *LValueFrom;    /* if an LValue, this is a Value our LValue is contained within (or NULL) */
    
};


#endif
